package cn.schoolwow.quickflow.service.quickFlow.option;

import cn.schoolwow.quickflow.QuickFlow;
import cn.schoolwow.quickflow.domain.FlowConfig;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.listener.FlowConfigRequestDataHandler;
import cn.schoolwow.quickflow.listener.FlowMappingHandler;
import cn.schoolwow.quickflow.listener.SingleFlowListener;
import cn.schoolwow.quickflow.listener.TryCatchFinallyHandler;
import com.alibaba.fastjson.JSONObject;

import java.util.Map;

public class QuickFlowOptionImpl implements QuickFlowOption{
    private FlowConfig flowConfig;

    public QuickFlowOptionImpl(FlowConfig flowConfig) {
        this.flowConfig = flowConfig;
    }

    @Override
    public QuickFlow startDebugMode() {
        flowConfig.flowConfigSwitcherContext.debug = true;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow stopDebugMode() {
        flowConfig.flowConfigSwitcherContext.debug = false;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow checkRepeatKeyName(boolean checkRepeatKeyName) {
        flowConfig.flowConfigSwitcherContext.checkRepeatKeyName = checkRepeatKeyName;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow printTrace(boolean printTrace) {
        flowConfig.flowConfigSwitcherContext.printTrace = printTrace;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow traceLevel(int traceLevel) {
        flowConfig.flowConfigSwitcherContext.traceLevel = traceLevel;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow ignoreBroken(boolean ignoreBroken) {
        flowConfig.flowConfigSwitcherContext.ignoreBroken = ignoreBroken;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow ignoreException(boolean ignoreException) {
        flowConfig.flowConfigSwitcherContext.ignoreException = ignoreException;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow flowNameInstanceMappingHandler(FlowMappingHandler flowMappingHandler) {
        flowConfig.flowConfigHandlerContext.flowMappingHandler = flowMappingHandler;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow tryCatchFinallyHandler(TryCatchFinallyHandler tryCatchFinallyHandler) {
        flowConfig.flowConfigHandlerContext.tryCatchFinallyHandler = tryCatchFinallyHandler;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow tryCatchFinallyHandler(TryCatchFinallyHandler... tryCatchFinallyHandlerArray) {
        if(null==tryCatchFinallyHandlerArray){
            return flowConfig.quickFlow;
        }
        for(TryCatchFinallyHandler tryCatchFinallyHandler:tryCatchFinallyHandlerArray){
            if(null==tryCatchFinallyHandler.name()||tryCatchFinallyHandler.name().isEmpty()){
                throw new IllegalArgumentException("监听器名称不能为空!监听器类名:"+tryCatchFinallyHandler.getClass().getName());
            }
        }
        flowConfig.flowConfigHandlerContext.tryCatchFinallyHandler = new TryCatchFinallyHandler() {
            @Override
            public void handleTryStart(FlowContext flowContext) throws Exception {
                for(TryCatchFinallyHandler tryCatchFinallyHandler:tryCatchFinallyHandlerArray){
                    try {
                        tryCatchFinallyHandler.handleTryStart(flowContext);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void handleTryEnd(FlowContext flowContext) throws Exception {
                for(TryCatchFinallyHandler tryCatchFinallyHandler:tryCatchFinallyHandlerArray){
                    try {
                        tryCatchFinallyHandler.handleTryEnd(flowContext);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void handleException(FlowContext flowContext, Exception e) {
                for(TryCatchFinallyHandler tryCatchFinallyHandler:tryCatchFinallyHandlerArray){
                    try {
                        tryCatchFinallyHandler.handleException(flowContext, e);
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }
                }
            }

            @Override
            public void handleFinally(FlowContext flowContext) {
                for(TryCatchFinallyHandler tryCatchFinallyHandler:tryCatchFinallyHandlerArray){
                    try {
                        tryCatchFinallyHandler.handleFinally(flowContext);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public String name() {
                return "综合TryCatchFinally处理器";
            }
        };
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow singleFlowListener(SingleFlowListener singleFlowListener) {
        if(null==singleFlowListener){
            return flowConfig.quickFlow;
        }
        if(null==singleFlowListener.name()||singleFlowListener.name().isEmpty()){
            throw new IllegalArgumentException("监听器名称不能为空!监听器类名:"+singleFlowListener.getClass().getName());
        }
        flowConfig.flowConfigHandlerContext.singleFlowListener = singleFlowListener;
        return flowConfig.quickFlow;
    }

    @Override
    public QuickFlow flowConfigRequestDataHandler(FlowConfigRequestDataHandler flowConfigRequestDataHandler) {
        if(null==flowConfigRequestDataHandler){
            return flowConfig.quickFlow;
        }
        flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler = flowConfigRequestDataHandler;
        try {
            Map<String, JSONObject> flowConfigMap = flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler.loadFlowConfigRequestDataMap();
            if(null!=flowConfigMap&&!flowConfigMap.isEmpty()){
                flowConfig.flowConfigDataContext.flowConfigDataMap.putAll(flowConfigMap);
            }
            return flowConfig.quickFlow;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public JSONObject getFlowConfigRequestData(String name) {
        if(!flowConfig.flowConfigDataContext.flowConfigDataMap.containsKey(name)){
            throw new IllegalArgumentException("流程配置数据不存在!流程名称:"+name);
        }
        JSONObject requestData = flowConfig.flowConfigDataContext.flowConfigDataMap.get(name);
        return requestData;
    }

    @Override
    public QuickFlow saveFlowConfigRequestData(String categoryName, String name, JSONObject requestData) {
        flowConfig.flowConfigDataContext.flowConfigDataMap.put(name, requestData);
        if(null==flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler){
            throw new IllegalArgumentException("请配置FlowConfigHandler处理器!");
        }
        try {
            flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler.saveFlowConfigRequestData(categoryName, name, requestData);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return flowConfig.quickFlow;
    }

    @Override
    public FlowConfig getFlowConfig() {
        return flowConfig;
    }

}
